package com.itheima.prize.msg;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itheima.prize.commons.config.RabbitKeys;
import com.itheima.prize.commons.config.RedisKeys;
import com.itheima.prize.commons.db.entity.*;
import com.itheima.prize.commons.db.service.CardGameProductService;
import com.itheima.prize.commons.db.service.CardGameRulesService;
import com.itheima.prize.commons.db.service.CardGameService;
import com.itheima.prize.commons.db.service.GameLoadService;
import com.itheima.prize.commons.utils.RedisUtil;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 活动信息预热，每隔1分钟执行一次
 * 查找未来1分钟内（含），要开始的活动
 */
@Component
public class GameTask {
    private final static Logger log = LoggerFactory.getLogger(GameTask.class);
    @Autowired
    private CardGameService gameService;
    @Autowired
    private CardGameProductService gameProductService;
    @Autowired
    private CardGameRulesService gameRulesService;
    @Autowired
    private GameLoadService gameLoadService;
    @Autowired
    private RedisUtil redisUtil;

    @Scheduled(cron = "*/30 * * * * ?")
    public void execute() {
        System.out.printf("scheduled!"+new Date());
        // 查询未来1分钟内（含），要开始的活动
        LocalDateTime now = LocalDateTime.now();
        List<CardGame> games = gameService.list(new QueryWrapper<CardGame>()
                .gt("starttime", now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                .le("starttime", now.plusMinutes(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
        // 预热活动信息
        for (CardGame game : games) {
            gameTask(game);
        }
    }
    public void gameTask(CardGame game){
        // 预热活动信息
        // 1.获取活动规则
        List<CardGameRules> rules = gameRulesService.list(new QueryWrapper<CardGameRules>()
                .eq("gameid", game.getId()));
        // 2.将活动信息缓存
        redisUtil.set(RedisKeys.INFO+game.getId(),game,-1);
        // 3.将活动规则缓存
        for (CardGameRules r : rules) {
            redisUtil.hset(RedisKeys.MAXGOAL +
                    game.getId(),r.getUserlevel()+"",r.getGoalTimes());
            redisUtil.hset(RedisKeys.MAXENTER +
                    game.getId(),r.getUserlevel()+"",r.getEnterTimes());
        }
        // 4.获取活动奖品
        List<CardProductDto> cardProducts = gameLoadService.getByGameId(game.getId());
        // 5.生成时间戳token
        ArrayList<Long> tokenList = new ArrayList<>();
        for (CardProductDto cardProduct : cardProducts) {
            long duration = game.getEndtime().getTime()-game.getStarttime().getTime();
            long rnd = game.getStarttime().getTime() + new Random().nextInt((int)duration);
            //为什么乘1000，再额外加一个随机数呢？ - 防止时间段奖品多时重复
            long token = rnd * 1000 + new Random().nextInt(999);
            tokenList.add(token);
            // 令牌奖品映射
            redisUtil.set(RedisKeys.TOKEN + game.getId() +"_"+token,cardProduct,duration);
        }
        // 6.对奖品tokens进行排序(从小到大)
        Collections.sort(tokenList);
        // 7.将奖品tokens缓存
        redisUtil.rightPushAll(RedisKeys.TOKENS + game.getId(),tokenList);
    }
}
